#include <channels/messages_channels.hpp>
#include <stdexcept>

using namespace ::fasys::channels;
messages_channels mcc;
time_t now = time(0);

message_notify publish_message(const std::string& name, const std::string& data, time_t lifetime , size_t limit )
{
  message_publish mp;
  message_notify mn;
  mp.channel = name;
  mp.content.assign( data.begin(), data.end() );
  mp.lifetime = lifetime;
  mp.limit = limit;
  mcc.publish(mp, mn);
  return mn;
}

bool check_message(const message_notify& m, const std::string& name, const std::string& data, time_t lifetime , size_t limit)
{
  if ( m.channel != name )
    return false;

  if ( std::string(m.content.begin(), m.content.end())!= data)
    return false;

  if ( m.lifetime != lifetime )
    return false;

  if ( m.limit != limit )
    return false;

  return true;
}

bool check_message(const message_list_item& m, const std::string& data, time_t lifetime)
{

  if ( std::string(m.content.begin(), m.content.end())!= data)
    return false;

  if ( m.lifetime != lifetime )
    return false;

  return true;
}

bool test1()
{
  message_notify m = publish_message("channel1", "test1 data", 1, 2);
  if ( !check_message(m, "channel1", "test1 data", 1, 2) )
    return false;
  if (m.count!=1)
    return false;
  if (m.death_time!=now + 1)
    return false;
  if (m.death_timespan!=1)
    return false;

  m = publish_message("channel1", "test1 data", 1, 2);
  if ( !check_message(m, "channel1", "test1 data", 1, 2) )
    return false;
  if (m.count!=2)
    return false;
  if (m.death_time!=now + 1)
    return false;
  if (m.death_timespan!=1)
    return false;

  m = publish_message("channel1", "test1 data2", 1, 2);
  if ( !check_message(m, "channel1", "test1 data2", 1, 2) )
    return false;
  if (m.count!=2)
    return false;
  if (m.death_time!=now + 1)
    return false;
  if (m.death_timespan!=1)
    return false;

  m = publish_message("channel1", "test1 data1", 1, 1);
  if ( !check_message(m, "channel1", "test1 data1", 1, 1) )
    return false;
  if (m.count!=1)
    return false;
  if (m.death_time!=now + 1)
    return false;
  if (m.death_timespan!=1)
    return false;

  m = publish_message("channel1", "test1 data1", 1, 0);
  if ( !check_message(m, "channel1", "test1 data1", 1, 0) )
    return false;
  if (m.count!=0)
    return false;
  if (m.death_time!=now + 1)
    return false;
  if (m.death_timespan!=1)
    return false;
  return true;
};

bool test2()
{
  publish_message("channel1", "test2 data1", 1, 2);
  publish_message("channel1", "test2 data1", 1, 2);
  publish_message("channel1", "test2 data1", 1, 3);
  publish_message("channel2", "test2 data2", 1, 1);

  message_list_request mlrq;
  message_list_response mlrs;
  mlrq.channel = "channel1";
  mlrq.limit = 10;
  mcc.query(mlrq, mlrs);

  if (mlrs.count!=3)
    return false;

  if (mlrs.message_list.size()!=3)
    return false;

  message_list_response::message_list_type::iterator itr = mlrs.message_list.begin();
  for ( ; itr!=mlrs.message_list.end(); ++itr)
  {
    if ( !check_message(*itr, "test2 data1", 1) )
      return false;
  }

  return true;
}



int main()
{
  if (!test1())
    return 1;
  
  if (!test2())
    return 2;
//throw std::logic_error("yo");
  return 0;
}